<template>
  <div class="app-container">
    <el-row :gutter="20">
      <splitpanes class="default-theme">
        <!-- 结构树 -->
        <pane size="25">
          <div class="panel-container">
            <div class="panel-header">结构列表</div>
            <div class="search-box">
              <el-input
                v-model="structName"
                placeholder="请输入结构名称"
                clearable
                size="small"
                prefix-icon="el-icon-search" />
            </div>
            <div class="panel-body">
              <el-tree
                :data="structOptions"
                :props="defaultProps"
                :expand-on-click-node="false"
                :filter-node-method="filterStructNode"
                ref="structTree"
                node-key="id"
                default-expand-all
                highlight-current
                @node-click="handleStructNodeClick">
                <span class="tree-node-name" slot-scope="{ node, data }">
                  <i :class="data.isdir === 'Y' ? 'el-icon-folder' : 'el-icon-document'" class="node-icon"></i>
                  {{ node.label }}
                </span>
              </el-tree>
            </div>
          </div>
        </pane>

        <!-- 映射列表区域 -->
        <pane size="75">
          <div class="panel-container">
            <div class="mapping-header">
              <div class="header-title">
                <span class="main-title">映射管理</span>
                <span class="sub-title" v-if="currentStruct">{{ currentStruct.name }}</span>
              </div>
              <div class="header-actions">
                <div class="action-wrapper">
                  <el-tooltip content="刷新数据" placement="top">
                    <el-button
                      type="primary"
                      class="business-button"
                      @click="getDirectMappingList"
                    >
                      <i class="el-icon-refresh"></i>
                      <span>刷新</span>
                    </el-button>
                  </el-tooltip>
                  <el-tooltip content="配置映射" placement="top">
                    <el-button
                      type="primary"
                      icon="el-icon-connection"
                      class="mapping-btn"
                      @click="goToMappingConfig">
                      配置映射
                    </el-button>
                  </el-tooltip>
                </div>
              </div>
            </div>

            <el-tabs v-model="activeTab" type="card" class="mapping-tabs">
              <!-- 直接映射 -->
              <el-tab-pane label="直接映射" name="direct">
                <el-table
                  v-loading="loading"
                  :data="directMappingList"
                  border
                  stripe
                  highlight-current-row
                  style="width: 100%"
                  @selection-change="handleSelectionChange">
                  <el-table-column label="需求名称" min-width="200" show-overflow-tooltip>
                    <template slot-scope="scope">
                      <div class="cell-content">
                        <i class="el-icon-tickets cell-icon"></i>
                        <span>{{ scope.row.demandName }}</span>
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column label="需求类型" width="120" align="center">
                    <template slot-scope="scope">
                      <el-tag size="medium" :type="getTypeTagType(scope.row.demandType)" effect="plain">
                        {{ getTypeName(scope.row.demandType) }}
                      </el-tag>
                    </template>
                  </el-table-column>
                  <el-table-column label="需求值" min-width="120" align="center">
                    <template slot-scope="scope">
                      <span>{{ scope.row.demandValue }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="技术指标名称" min-width="200" show-overflow-tooltip>
                    <template slot-scope="scope">
                      <div class="cell-content">
                        <i class="el-icon-data-analysis cell-icon"></i>
                        <span>{{ scope.row.indicatorName }}</span>
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column label="指标类型" width="120" align="center">
                    <template slot-scope="scope">
                      <el-tag size="medium" :type="getTypeTagType(scope.row.indicatorType)" effect="plain">
                        {{ getTypeName(scope.row.indicatorType) }}
                      </el-tag>
                    </template>
                  </el-table-column>
                  <el-table-column label="指标值" min-width="120" align="center">
                    <template slot-scope="scope">
                      <span>{{ scope.row.indicatorValue }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="操作" width="120" align="center" fixed="right">
                    <template slot-scope="scope">
                      <el-tooltip content="删除此项" placement="top">
                        <el-button
                          type="text"
                          class="table-action-button"
                          @click="handleDelete(scope.row)"

                        >
                          <i class="el-icon-delete"></i>
                          <span>删除</span>
                        </el-button>
                      </el-tooltip>
                    </template>
                  </el-table-column>
                </el-table>
              </el-tab-pane>

              <!-- 知识映射 -->
              <el-tab-pane label="知识映射" name="knowledge_mapping">
                <el-table
                  v-loading="mappingResultsLoading"
                  :data="processedMappingResults"
                  border
                  stripe
                  highlight-current-row
                  style="width: 100%"
                  @selection-change="handleKnowledgeMappingSelectionChange">
                  <el-table-column label="需求名称" min-width="180" show-overflow-tooltip>
                    <template slot-scope="scope">
                      <div class="cell-content">
                        <i class="el-icon-tickets cell-icon"></i>
                        <span>{{ scope.row.demandName }}</span>
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column label="需求类型" width="100" align="center">
                    <template slot-scope="scope">
                      <el-tag size="medium" :type="getTypeTagType(scope.row.demandType)" effect="plain">
                        {{ getTypeName(scope.row.demandType) }}
                      </el-tag>
                    </template>
                  </el-table-column>
                  <el-table-column label="技术指标名称" min-width="180" show-overflow-tooltip>
                    <template slot-scope="scope">
                      <div class="cell-content">
                        <i class="el-icon-data-analysis cell-icon"></i>
                        <span>{{ scope.row.indicatorName }}</span>
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column label="指标类型" width="100" align="center">
                    <template slot-scope="scope">
                      <el-tag size="medium" :type="getTypeTagType(scope.row.indicatorType)" effect="plain">
                        {{ getTypeName(scope.row.indicatorType) }}
                      </el-tag>
                    </template>
                  </el-table-column>
                  <el-table-column label="映射数量" width="100" align="center">
                    <template slot-scope="scope">
                      <span class="mapping-count">{{ scope.row.mappings.length }}</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="详情" width="120" align="center">
                    <template slot-scope="scope">
                      <el-tooltip content="查看详情" placement="top">
                        <el-button
                          type="text"
                          class="table-action-button view-button"
                          @click="viewMappingDetails(scope.row)">
                          <i class="el-icon-view"></i>
                          <span>详情</span>
                        </el-button>
                      </el-tooltip>
                    </template>
                  </el-table-column>
                  <el-table-column label="操作" width="120" align="center" fixed="right">
                    <template slot-scope="scope">
                      <el-tooltip content="删除此项" placement="top">
                        <el-button
                          type="text"
                          class="table-action-button"
                          @click="handleKnowledgeMappingDelete(scope.row)"
                        >
                          <i class="el-icon-delete"></i>
                          <span>删除</span>
                        </el-button>
                      </el-tooltip>
                    </template>
                  </el-table-column>
                </el-table>
              </el-tab-pane>

              <!-- 函数映射 -->
              <el-tab-pane label="函数映射" name="function">
                <el-table
                  ref="functionMappingTable"
                  v-loading="functionMappingLoading"
                  :data="mergedFunctionMappings"
                  border
                  stripe
                  highlight-current-row
                  style="width: 100%"
                  @selection-change="handleFunctionMappingSelectionChange">
                  <!-- 技术指标信息 -->
                  <el-table-column label="技术指标名称" min-width="180" show-overflow-tooltip>
                    <template slot-scope="scope">
                      <div class="cell-content">
                        <i class="el-icon-data-analysis cell-icon"></i>
                        <span>{{ scope.row.indicatorName }}</span>
                      </div>
                    </template>
                  </el-table-column>

                  <el-table-column label="指标类型" width="100" align="center">
                    <template slot-scope="scope">
                      <el-tag size="medium" :type="getTypeTagType(scope.row.indicatorType)" effect="plain">
                        {{ getTypeName(scope.row.indicatorType) }}
                      </el-tag>
                    </template>
                  </el-table-column>

                  <!-- 需求和变量关系 -->
                  <el-table-column label="需求与变量" min-width="180">
                    <template slot-scope="scope">
                      <el-popover
                        placement="right"
                        width="400"
                        trigger="hover">
                        <div class="demands-popover">
                          <div class="demands-popover-title">需求变量列表</div>
                          <div class="demands-popover-content">
                            <!-- Group demands by name and show unique demand names with their variables -->
                            <div v-for="(groupedDemand, index) in groupDemandsByName(scope.row.demands)"
                                :key="groupedDemand.name"
                                class="demand-item"
                                :class="{'with-divider': index < Object.keys(groupDemandsByName(scope.row.demands)).length - 1}">
                              <div class="demand-item-header">
                                <el-tag size="mini" :type="getTypeTagType(groupedDemand.type)" effect="plain">
                                  {{ getTypeName(groupedDemand.type) }}
                                </el-tag>
                                <span class="demand-name">{{ groupedDemand.name }}</span>
                              </div>
                              <!-- Show all variables for this demand -->
                              <div class="demand-variables-list">
                                <div v-for="(variable, vIndex) in groupedDemand.variables" :key="vIndex"
                                    class="demand-variable" :class="{'variable-divider': vIndex > 0}">
                                  <i class="el-icon-arrow-right"></i>
                                  <span class="variable-name">{{ variable }}</span>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                        <div slot="reference" class="demands-preview">
                          <el-tag type="info" effect="plain" class="count-tag">
                            <i class="el-icon-document"></i>
                            <!-- Show unique demand count instead of total -->
                            <span>{{ Object.keys(groupDemandsByName(scope.row.demands)).length }}</span> 个需求
                          </el-tag>
                          <div class="demands-preview-hint">
                            <i class="el-icon-info-circle"></i>
                            <span>悬停查看详情</span>
                          </div>
                        </div>
                      </el-popover>
                    </template>
                  </el-table-column>

                  <!-- 映射公式 -->
                  <el-table-column label="映射公式" min-width="200" show-overflow-tooltip>
                    <template slot-scope="scope">
                      <div class="formula-cell">
                        <i class="el-icon-edit-outline cell-icon"></i>
                        <el-popover
                          placement="top"
                          width="300"
                          trigger="hover">
                          <div class="formula-popover">
                            <div class="formula-title">映射公式</div>
                            <div class="formula-content">{{ scope.row.formula }}</div>
                          </div>
                          <span slot="reference" class="formula-text">{{ scope.row.formula }}</span>
                        </el-popover>
                      </div>
                    </template>
                  </el-table-column>

                  <el-table-column label="单位" width="100" align="center">
                    <template slot-scope="scope">
                      <span>{{ scope.row.unit || '-' }}</span>
                    </template>
                  </el-table-column>

                  <el-table-column label="操作" width="120" align="center" fixed="right">
                    <template slot-scope="scope">
                      <el-tooltip content="删除此项" placement="top">
                        <el-button
                          type="text"
                          class="table-action-button"
                          @click="deleteFunctionMapping(scope.row)"
                        >
                          <i class="el-icon-delete"></i>
                          <span>删除</span>
                        </el-button>
                      </el-tooltip>
                    </template>
                  </el-table-column>
                </el-table>
              </el-tab-pane>
            </el-tabs>
          </div>
        </pane>
      </splitpanes>
    </el-row>
  </div>
</template>

<script>
import { Splitpanes, Pane } from "splitpanes";
import "splitpanes/dist/splitpanes.css";
import { listStruct } from "@/api/data/struct";
import { getDirectMappingBySid, delDirectMapping, removeDirectMapping } from "@/api/data/direct_mapping";
import {
  getKnowledgeMappingResultsBySid,
  delKnowledgeMapping
} from "@/api/data/knowledge_mapping";
// 导入函数映射相关API
import {
  getFunctionMappingResultBySid,
  getFunctionMappingResultById,
  delFunctionMapping,
  removeFunctionMapping,
  delFunctionMappingBySiid,
  delFunctionMappingBySiids
} from "@/api/data/function_mapping";

export default {
  name: "MappingManage",
  components: { Splitpanes, Pane },
  data() {
    return {
      // 遮罩层
      loading: true,
      mappingResultsLoading: false,
      functionMappingLoading: false, // 函数映射加载状态
      // 当前选中的tab
      activeTab: 'direct',
      // 选中的映射ID数组
      selectedIds: [],
      // 选中的知识映射ID数组
      selectedKnowledgeMappingIds: [],
      // 选中的函数映射ID数组
      selectedFunctionMappingIds: [],
      // 结构树相关
      structName: undefined,
      structOptions: [],
      defaultProps: {
        children: "children",
        label: "name"
      },
      // 当前选中的结构节点
      currentStruct: null,
      // 直接映射列表
      directMappingList: [],
      // 知识映射结果列表
      mappingResultsList: [],
      // 函数映射结果列表
      functionMappingResults: [],
      mergedFunctionMappings: [], // 合并后的函数映射结果
    };
  },
  computed: {
    // 处理后的映射结果（合并相同需求和技术指标的项）
    processedMappingResults() {
      const groupedMappings = {};

      console.log("正在处理映射结果，原始数据:", this.mappingResultsList);

      // 按需求名称和技术指标名称分组，而不是ID
      this.mappingResultsList.forEach(item => {
        const demandName = item.demandName;
        const indicatorName = item.indicatorName;

        if (!demandName || !indicatorName) {
          console.warn("映射项缺少名称字段:", item);
          return; // 跳过没有必要名称的项
        }

        const key = `${demandName}_${indicatorName}`;
        if (!groupedMappings[key]) {
          groupedMappings[key] = {
            id: key,
            demandId: item.doid,
            demandName: demandName,
            demandType: item.demandType,
            indicatorId: item.ioid,
            indicatorName: indicatorName,
            indicatorType: item.indicatorType,
            originalIds: [], // 存储原始ID，用于删除操作
            mappings: []
          };
        }

        // 添加映射信息
        groupedMappings[key].originalIds.push(item.id);
        groupedMappings[key].mappings.push({
          id: item.id,
          demandOptionValue: item.demandOptionValue,
          indicatorOptionValue: item.indicatorOptionValue,
          mappingRule: ''  // 如果后端没返回mappingRule，使用空字符串
        });
      });

      const result = Object.values(groupedMappings);
      console.log("处理后的映射结果:", result);
      return result;
    },
    // 当前选中的函数映射行
    selectedFunctionMappingRows() {
      return this.$refs.functionMappingTable ?
        this.$refs.functionMappingTable.selection : [];
    }
  },
  watch: {
    structName(val) {
      this.$refs.structTree.filter(val);
    },
    activeTab(val) {
      if (val === 'knowledge_mapping' && this.currentStruct) {
        this.getMappingResultsList();
      } else if (val === 'direct' && this.currentStruct) {
        this.getDirectMappingList();
      } else if (val === 'function' && this.currentStruct) {
        this.getFunctionMappingResults();
      }
    }
  },
  created() {
    this.getStructTree();
  },
  methods: {
    /** 获取结构树数据 */
    getStructTree() {
      this.loading = true;
      listStruct().then(response => {
        this.structOptions = this.handleTree(response.data, "id", "pid");
        this.loading = false;
      });
    },

    /** 过滤结构树节点 */
    filterStructNode(value, data) {
      if (!value) return true;
      return data.name.toLowerCase().includes(value.toLowerCase());
    },

    /** 结构树节点点击事件 */
    handleStructNodeClick(data) {
      this.currentStruct = data;
      if (this.activeTab === 'direct') {
        this.getDirectMappingList();
      } else if (this.activeTab === 'knowledge_mapping') {
        this.getMappingResultsList();
      } else if (this.activeTab === 'function') {
        this.getFunctionMappingResults();
      }
    },

    /** 获取直接映射列表 */
    getDirectMappingList() {
      if (!this.currentStruct) return;

      this.loading = true;
      getDirectMappingBySid(this.currentStruct.id).then(response => {
        this.directMappingList = response.data;
        this.loading = false;
      });
    },

    /** 获取知识映射结果列表 */
    getMappingResultsList() {
      if (!this.currentStruct) return;

      this.mappingResultsLoading = true;
      this.selectedKnowledgeMappingIds = []; // 重置选中项

      getKnowledgeMappingResultsBySid(this.currentStruct.id).then(response => {
        console.log("获取知识映射结果:", response);
        this.mappingResultsList = response.data || [];
        this.mappingResultsLoading = false;
      }).catch(error => {
        console.error("获取知识映射结果失败:", error);
        this.mappingResultsList = [];
        this.mappingResultsLoading = false;
      });
    },

    /** 获取函数映射结果 */
    getFunctionMappingResults() {
      if (!this.currentStruct || !this.currentStruct.id) return;

      this.functionMappingLoading = true;

      getFunctionMappingResultBySid(this.currentStruct.id)
        .then(response => {
          const results = response.data || [];
          this.processFunctionMappingResults(results);
        })
        .catch(error => {
          this.$message.error('获取函数映射结果失败: ' + error.message);
        })
        .finally(() => {
          this.functionMappingLoading = false;
        });
    },

    // 处理函数映射结果，合并相同指标的项
    processFunctionMappingResults(results) {
      // 按指标ID分组
      const groupedMappings = {};

      results.forEach(item => {
        const siid = item.siid;
        if (!groupedMappings[siid]) {
          groupedMappings[siid] = {
            id: `func_${siid}`,
            siid: siid,
            demands: [],
            indicatorName: item.indicatorName,
            indicatorType: item.indicatorType,
            formula: item.formula,
            unit: item.unit || '',
            cnt: parseInt(item.cnt) || 0,
            originalIds: []
          };
        }

        // 添加需求信息
        groupedMappings[siid].demands.push({
          sdid: item.sdid,
          demandName: item.demandName,
          demandType: item.demandType,
          variable: item.variable
        });

        // 存储原始ID，用于删除操作
        groupedMappings[siid].originalIds.push(item.id);
      });

      this.mergedFunctionMappings = Object.values(groupedMappings);
    },

    /** 函数映射选择项发生变化 */
    handleFunctionMappingSelectionChange(selection) {
      // 合并所有ID为一个数组
      this.selectedFunctionMappingIds = [];
      selection.forEach(item => {
        if (item.originalIds && item.originalIds.length > 0) {
          this.selectedFunctionMappingIds.push(...item.originalIds);
        } else if (item.id) {
          this.selectedFunctionMappingIds.push(item.id);
        }
      });
    },

    /** 添加函数映射 */
    handleAddFunctionMapping() {
      // 实现新增函数映射逻辑
    },

    /** 编辑函数映射 */
    handleEditFunctionMapping(row) {
      // 实现编辑函数映射逻辑
    },

    /** 删除函数映射 */
    deleteFunctionMapping(row) {
      const ids = row.originalIds;
      if (!ids || ids.length === 0) {
        this.$message.warning('没有找到需要删除的映射ID');
        return;
      }

      this.$confirm('确认删除选中的函数映射？', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.functionMappingLoading = true;

        // 批量删除
        removeFunctionMapping(ids.join(',')).then(response => {
          this.$message.success('删除成功');
          this.getFunctionMappingResults();
        }).catch(error => {
          this.$message.error('删除失败: ' + error.message);
        }).finally(() => {
          this.functionMappingLoading = false;
        });
      }).catch(() => {});
    },

    /** 批量删除函数映射 */
    handleBatchFunctionMappingDelete() {
      const rows = this.$refs.functionMappingTable ? this.$refs.functionMappingTable.selection : [];
      console.log("批量删除选中行:", rows);

      if (rows.length === 0) {
        this.$message.warning("请至少选择一条记录");
        return;
      }

      this.$confirm('是否确认删除选中的函数映射?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        // 收集所有siid和id
        const siids = [];
        const ids = [];

        console.log("开始处理选中的" + rows.length + "行数据");

        rows.forEach((row, index) => {
          console.log(`处理第${index+1}行:`, row);
          if (row.siid) {
            console.log(`添加siid到删除列表: ${row.siid}`);
            if (!siids.includes(row.siid)) {
              siids.push(row.siid);
            }
          } else if (row.originalIds && row.originalIds.length) {
            console.log(`添加originalIds到删除列表:`, row.originalIds);
            row.originalIds.forEach(id => {
              if (!ids.includes(id)) {
                ids.push(id);
              }
            });
          } else if (row.id) {
            console.log(`添加id到删除列表: ${row.id}`);
            if (!ids.includes(row.id)) {
              ids.push(row.id);
            }
          } else {
            console.warn("警告：此行没有可用于删除的ID:", row);
          }
        });

        const promises = [];

        // 批量删除siid - 一个一个删除以确保全部成功
        console.log("需要删除的siids:", siids);
        for (const siid of siids) {
          console.log(`准备删除siid: ${siid}`);
          promises.push(delFunctionMappingBySiid(siid).then(res => {
            console.log(`成功删除siid: ${siid}, 响应:`, res);
            return res;
          }));
        }

        // 批量删除id
        if (ids.length > 0) {
          console.log("需要删除的ids:", ids);
          console.log("批量删除ids: " + ids.join(','));
          promises.push(removeFunctionMapping(ids.join(',')).then(res => {
            console.log("批量删除ids成功，响应:", res);
            return res;
          }));
        }

        console.log("总共创建" + promises.length + "个删除请求");

        return Promise.all(promises);
      }).then((results) => {
        console.log("所有删除请求完成，结果:", results);
        this.getFunctionMappingResults();
        this.$message.success("删除成功");
      }).catch(err => {
        if (err && err !== 'cancel') {
          console.error("批量删除失败:", err);
          this.$message.error("删除失败: " + (err.message || err));
        } else {
          console.log("用户取消删除");
        }
      });
    },

    /** 获取类型名称 */
    getTypeName(type) {
      switch(type) {
        case 'text': return '文本';
        case 'num': return '数字';
        case 'range': return '范围';
        case 'option': return '选项';
        default: return '未知';
      }
    },

    /** 获取类型标签样式 */
    getTypeTagType(type) {
      switch(type) {
        case 'text': return 'success';
        case 'num': return 'primary';
        case 'range': return 'warning';
        case 'option': return 'info';
        default: return '';
      }
    },

    /** 单个知识映射删除 */
    handleKnowledgeMappingDelete(row) {
      const mappingIds = row.originalIds;
      this.$confirm('是否确认删除选中的知识映射?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        return Promise.all(mappingIds.map(id => delKnowledgeMapping(id)));
      }).then(() => {
        this.getMappingResultsList();
        this.$message.success("删除成功");
      }).catch(() => {});
    },

    /** 批量删除知识映射 */
    handleBatchKnowledgeMappingDelete() {
      const mappingIds = this.selectedKnowledgeMappingIds;
      if (mappingIds.length === 0) {
        return;
      }

      this.$confirm('是否确认删除选中的知识映射?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        return Promise.all(mappingIds.map(id => delKnowledgeMapping(id)));
      }).then(() => {
        this.getMappingResultsList();
        this.$message.success("批量删除成功");
      }).catch(() => {});
    },

    /** 查看映射详情 */
    viewMappingDetails(row) {
      console.log("查看映射详情:", row);

      // 构建映射项HTML
      let mappingsHtml = '';

      if (row.mappings && row.mappings.length) {
        const mappingRows = row.mappings.map(m => `
          <div class="table-row" data-id="${m.id}">
            <div class="table-cell demand-column">
              <div class="mapping-item-cell">
                <i class="el-icon-tickets cell-icon demand-icon"></i>
                <span>${m.demandOptionValue || '-'}</span>
              </div>
            </div>
            <div class="table-cell indicator-column">
              <div class="mapping-item-cell">
                <i class="el-icon-data-analysis cell-icon indicator-icon"></i>
                <span>${m.indicatorOptionValue || '-'}</span>
              </div>
            </div>
            <div class="table-cell action-column">
              <button class="delete-btn" onclick="deleteMapping('${m.id}')">
                <i class="el-icon-delete"></i>
              </button>
            </div>
          </div>
        `).join('');

        mappingsHtml = `
          <div class="mappings-table">
            <div class="table-header">
              <div class="column-header demand-column">需求选项</div>
              <div class="column-header indicator-column">指标选项</div>
              <div class="column-header action-column">操作</div>
            </div>
            <div class="table-body">
              ${mappingRows}
            </div>
          </div>
        `;
            } else {
        mappingsHtml = `
          <div class="empty-mappings">
            <i class="el-icon-warning-outline"></i>
            <p class="empty-text">暂无映射关系数据</p>
          </div>
        `;
      }

      // 创建详情对话框内容
      const detailContent = `
        <div class="mapping-detail-container">
          <!-- 映射头部描述 -->
          <div class="mapping-header">
            <i class="el-icon-connection dialog-icon"></i>
            <span class="mapping-subtitle">映射关系详情展示需求项与技术指标之间的对应关系</span>
          </div>

          <!-- 主要内容区域 -->
          <el-row :gutter="24">
            <!-- 左侧需求信息 -->
            <el-col :span="12">
              <div class="mapping-section direct-mapping-section">
                <div class="section-title">
                  <i class="el-icon-document-checked"></i>
                  <span>需求项</span>
                  <el-tag type="primary" size="mini" class="item-tag">${this.getTypeName(row.demandType)}</el-tag>
                </div>
                <div class="section-content">
                  <div class="item-card">
                    <div class="item-name">${row.demandName}</div>
                    ${row.demandDesc ? `
                      <div class="item-desc">
                        <i class="el-icon-info"></i>
                        <span>${row.demandDesc}</span>
                      </div>
                    ` : ''}
                  </div>
                </div>
              </div>
            </el-col>

            <!-- 右侧指标信息 -->
            <el-col :span="12">
              <div class="mapping-section direct-mapping-section">
                <div class="section-title">
                  <i class="el-icon-data-analysis"></i>
                  <span>技术指标</span>
                  <el-tag type="success" size="mini" class="item-tag">${this.getTypeName(row.indicatorType)}</el-tag>
                </div>
                <div class="section-content">
                  <div class="item-card">
                    <div class="item-name">${row.indicatorName}</div>
                    ${row.indicatorDesc ? `
                      <div class="item-desc">
                        <i class="el-icon-info"></i>
                        <span>${row.indicatorDesc}</span>
                      </div>
                    ` : ''}
                  </div>
                </div>
              </div>
            </el-col>
          </el-row>

          <!-- 映射概览 -->
          <div class="mapping-summary">
            <div class="summary-title">
              <i class="el-icon-info"></i>
              <span>映射关系概览</span>
            </div>
            <div class="summary-content">
              <p>共有 <b>${row.mappings.length}</b> 条映射关系</p>
              <div class="mapping-preview">
                <div class="mapping-preview-left">
                  <div class="preview-text">需求项</div>
                </div>
                <div class="mapping-preview-arrow">
                  <i class="el-icon-right"></i>
                  <div class="preview-count">${row.mappings.length}</div>
                </div>
                <div class="mapping-preview-right">
                  <div class="preview-text">技术指标</div>
                </div>
              </div>
            </div>
          </div>

          <!-- 映射关系列表 -->
          <div class="mapping-list-container">
            <div class="mapping-list-title">
              <i class="el-icon-link"></i>
              <span>映射关系列表</span>
              <el-tag size="mini" type="info" class="count-tag">${row.mappings.length}</el-tag>
            </div>

            ${mappingsHtml}
          </div>
        </div>

        <style>
          .mapping-detail-container {
            padding: 0;
            max-height: calc(80vh - 200px);
            overflow-y: auto;
          }

          .mapping-header {
            display: flex;
            align-items: center;
            margin-bottom: 24px;
            padding: 14px 20px;
            background-color: #f8f8fc;
            border-radius: 4px;
            border-left: 4px solid #2d8cf0;
            box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
          }

          .dialog-icon {
            font-size: 24px;
            color: #2d8cf0;
            margin-right: 16px;
          }

          .mapping-subtitle {
            color: #515a6e;
            font-size: 14px;
            line-height: 1.6;
          }

          .mapping-section {
            height: 100%;
            box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.06);
            border: 1px solid #e8eaec;
            border-radius: 4px;
            transition: all 0.3s ease;
            margin-bottom: 20px;
          }

          .mapping-section:hover {
            box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.08);
          }

          .section-title {
            display: flex;
            align-items: center;
            padding: 12px 16px;
            background-color: #f8f8fc;
            border-bottom: 1px solid #e8eaec;
            font-weight: 600;
            color: #17233d;
            border-radius: 4px 4px 0 0;
          }

          .section-title i {
            font-size: 16px;
            margin-right: 8px;
            color: #2d8cf0;
          }

          .item-tag {
            margin-left: 8px;
          }

          .section-content {
            padding: 12px;
            background-color: white;
            border-radius: 0 0 4px 4px;
          }

          .item-card {
            padding: 12px;
            border: 1px solid #e8eaec;
            border-radius: 4px;
            background-color: #fafafa;
          }

          .item-name {
            font-size: 15px;
            font-weight: 500;
            color: #17233d;
            margin-bottom: 8px;
          }

          .item-desc {
            display: flex;
            align-items: flex-start;
            font-size: 13px;
            color: #808695;
            margin-top: 8px;
          }

          .item-desc i {
            margin-right: 6px;
            margin-top: 3px;
          }

          /* 映射总结 */
          .mapping-summary {
            margin-top: 24px;
            margin-bottom: 24px;
            border: 1px solid #e8eaec;
            border-radius: 4px;
            overflow: hidden;
            box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
          }

          .summary-title {
            display: flex;
            align-items: center;
            padding: 12px 16px;
            background-color: #f8f8fc;
            border-bottom: 1px solid #e8eaec;
            font-weight: 600;
            color: #17233d;
          }

          .summary-title i {
            color: #2d8cf0;
            margin-right: 8px;
          }

          .summary-content {
            padding: 20px;
          }

          .summary-content p {
            margin: 0 0 16px 0;
            color: #515a6e;
            font-size: 14px;
          }

          .mapping-preview {
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 24px;
            background-color: #f8fafc;
            border-radius: 4px;
            border: 1px dashed #d7dce6;
          }

          .mapping-preview-left, .mapping-preview-right {
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 16px 30px;
            background-color: white;
            border-radius: 4px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
            min-width: 120px;
            transition: transform 0.3s ease;
          }

          .mapping-preview-left:hover, .mapping-preview-right:hover {
            transform: translateY(-2px);
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
          }

          .mapping-preview-left {
            border-top: 3px solid #2d8cf0;
          }

          .mapping-preview-right {
            border-top: 3px solid #19be6b;
          }

          .preview-text {
            color: #808695;
            font-size: 14px;
          }

          .mapping-preview-arrow {
            margin: 0 24px;
            display: flex;
            flex-direction: column;
            align-items: center;
          }

          .mapping-preview-arrow i {
            font-size: 24px;
            color: #808695;
            background-color: #f0f4f9;
            border-radius: 50%;
            padding: 8px;
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
          }

          .preview-count {
            margin-top: 8px;
            font-size: 16px;
            font-weight: 600;
            color: #ed4014;
          }

          /* 映射列表 */
          .mapping-list-container {
            border: 1px solid #e8eaec;
            border-radius: 4px;
            overflow: hidden;
            box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);
          }

          .mapping-list-title {
            display: flex;
            align-items: center;
            padding: 12px 16px;
            background-color: #f8f8fc;
            border-bottom: 1px solid #e8eaec;
            font-weight: 600;
            color: #17233d;
          }

          .mapping-list-title i {
            color: #2d8cf0;
            margin-right: 8px;
          }

          .count-tag {
            margin-left: 8px;
          }

          .empty-mappings {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 40px 0;
            background-color: #fafafa;
          }

          .empty-mappings i {
            font-size: 32px;
            color: #c5c8ce;
            margin-bottom: 16px;
          }

          .empty-text {
            color: #808695;
            font-size: 14px;
          }

          /* 表格样式 */
          .mappings-table {
            width: 100%;
            border-collapse: collapse;
          }

          .table-header {
            display: flex;
            background-color: #f8f8fc;
            border-bottom: 1px solid #e8eaec;
          }

          .column-header {
            padding: 12px 16px;
            font-weight: 600;
            color: #17233d;
            text-align: left;
          }

          .demand-column, .indicator-column {
            flex: 1;
          }

          .action-column {
            width: 80px;
            text-align: center;
          }

          .table-body {
            background-color: white;
          }

          .table-row {
            display: flex;
            border-bottom: 1px solid #e8eaec;
            transition: all 0.3s;
          }

          .table-row:hover {
            background-color: #f5f7fa;
          }

          .table-row.deleting {
            background-color: #ffebeb;
            opacity: 0.5;
          }

          .table-cell {
            padding: 12px 16px;
            display: flex;
            align-items: center;
          }

          .mapping-item-cell {
            display: flex;
            align-items: center;
            width: 100%;
          }

          .cell-icon {
            margin-right: 8px;
            font-size: 14px;
          }

          .demand-icon {
            color: #2d8cf0;
          }

          .indicator-icon {
            color: #19be6b;
          }

          .delete-btn {
            background: none;
            border: none;
            color: #ed4014;
            cursor: pointer;
            padding: 4px 8px;
            border-radius: 4px;
            transition: all 0.3s;
          }

          .delete-btn:hover {
            background-color: #fff0f0;
          }
        </style>
      `;

      // 创建删除单个映射的方法
      window.deleteMapping = (id) => {
        // 直接删除，无需确认对话框
        delKnowledgeMapping(id).then(() => {
          // 提供即时反馈
          const mappingRow = document.querySelector(`.table-row[data-id="${id}"]`);
          if (mappingRow) {
            mappingRow.classList.add('deleting');
            setTimeout(() => {
              mappingRow.remove();

              // 更新计数
              const countTags = document.querySelectorAll('.count-tag');
              const previewCount = document.querySelector('.preview-count');
              const currentCount = document.querySelectorAll('.table-row').length;

              countTags.forEach(tag => tag.textContent = currentCount);
              if (previewCount) previewCount.textContent = currentCount;

              // 如果删除完所有项，显示空状态
              if (currentCount === 0) {
                const tableEl = document.querySelector('.mappings-table');
                if (tableEl) {
                  tableEl.innerHTML = `
                    <div class="empty-mappings">
                      <i class="el-icon-warning-outline"></i>
                      <p class="empty-text">暂无映射关系数据</p>
                    </div>
                  `;
                }
              }
            }, 300);
          }

          this.$message({
            type: 'success',
            message: '删除成功',
            duration: 1500
          });

          // 更新数据源
          this.getMappingResultsList();
        }).catch(error => {
          console.error("删除映射失败:", error);
          this.$message({
            type: 'error',
            message: '删除失败',
            duration: 1500
          });
        });
      };

      // 显示详情对话框
      this.$alert(
        detailContent,
        '知识映射详情',
        {
          dangerouslyUseHTMLString: true,
          showCancelButton: false,
          showConfirmButton: false,
          closeOnClickModal: false,
          closeOnPressEscape: true,
          customClass: 'mapping-detail-dialog',
          beforeClose: (action, instance, done) => {
            // 清除全局方法
            window.deleteMapping = undefined;
            done();
          }
        }
      );
    },

    /** 跳转到映射配置页面 */
    goToMappingConfig() {
      if (this.currentStruct) {
        this.$router.push({
          path: '/data/mapping_config',
          query: { structId: this.currentStruct.id }
        });
      } else {
        this.$message({
          message: '请先选择一个结构',
          type: 'warning'
        });
      }
    },

    /** 按需求名称分组 */
    groupDemandsByName(demands) {
      const grouped = {};

      demands.forEach(demand => {
        const demandName = demand.demandName;

        if (!grouped[demandName]) {
          grouped[demandName] = {
            name: demandName,
            type: demand.demandType,
            variables: [demand.variable]
          };
        } else {
          // If demand with same name exists, just add the variable
          if (!grouped[demandName].variables.includes(demand.variable)) {
            grouped[demandName].variables.push(demand.variable);
          }
        }
      });

      return grouped;
    },

    // 获取函数映射中的需求列表
    getFunctionMappingDemands(row) {
      return row.demands || [];
    },

    // 获取需求变量预览文本
    getDemandVariablesPreview(demands) {
      if (!demands || demands.length === 0) return '';

      // 如果超过2个需求，只显示前2个
      const visibleDemands = demands.slice(0, 2);
      const previewText = visibleDemands.map(d =>
        `${d.demandName}: ${d.variable}`
      ).join(', ');

      // 显示剩余需求数量
      const remaining = demands.length - visibleDemands.length;
      return remaining > 0
        ? `${previewText} 等${demands.length}个变量`
        : previewText;
    },

    /** 单个直接映射删除 */
    handleDelete(row) {
      if (!row || !row.id) {
        this.$message.warning('没有找到需要删除的映射ID');
        return;
      }

      this.$confirm('确认删除该直接映射?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      }).then(() => {
        this.loading = true;
        return delDirectMapping(row.id);
      }).then(() => {
        this.getDirectMappingList();
        this.$message.success("删除成功");
      }).catch((err) => {
        if (err && err !== 'cancel') {
          this.$message.error("删除失败: " + (err.message || err));
        }
      }).finally(() => {
        this.loading = false;
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.app-container {
  height: 100%;
  padding: 20px;
  background-color: #f3f4f7;
}

.panel-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
}

.search-box {
  padding: 12px 16px;
  border-bottom: 1px solid #f0f0f0;
}

.panel-body {
  flex: 1;
  overflow: auto;
  padding: 8px 0;
}

.tree-node-name {
  display: flex;
  align-items: center;
  height: 32px;

  .node-icon {
    margin-right: 8px;
    font-size: 14px;

    &.el-icon-folder {
      color: #E6A23C;
    }

    &.el-icon-document {
      color: #409EFF;
    }
  }
}

.panel-header {
  padding: 16px 20px;
  font-size: 16px;
  font-weight: 600;
  color: #17233d;
  background-color: #f8f8fc;
  border-bottom: 1px solid #e8eaec;
  display: flex;
  align-items: center;

  &::before {
    content: "";
    display: inline-block;
    width: 4px;
    height: 16px;
    border-radius: 2px;
    background-color: #2d8cf0;
    margin-right: 12px;
  }
}

/* 树状结构样式 - 使用与配置页面一致的样式 */
::v-deep .el-tree {
  background-color: transparent;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 10px;
  height: 100%;
  overflow: auto;

  /* 高亮选中的节点 */
  .el-tree-node.is-current > .el-tree-node__content {
    background-color: #ecf5ff;
    color: #409EFF;
  }

  /* 树节点样式 */
  .el-tree-node__content {
    height: 36px;
    border-radius: 3px;
    margin-bottom: 2px;
    transition: all 0.2s;

    &:hover {
      background-color: #f5f7fa;
    }
  }

  /* 缩进样式 */
  .el-tree-node__expand-icon {
    padding: 6px;
    color: #909399;
    transition: transform 0.3s;

    &.expanded {
      transform: rotate(90deg);
    }
  }

  /* 缩进样式 */
  .el-tree__indent {
    padding-left: 16px !important;
  }
}

.mapping-header {
  padding: 16px;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.mapping-tabs {
  height: calc(100% - 65px);

  ::v-deep {
    .el-tabs__header {
      margin: 0;
      padding: 0 16px;
      height: 40px;
      line-height: 40px;
    }

    .el-tabs__content {
      height: calc(100% - 40px);
      padding: 16px;

      .el-tab-pane {
        height: 100%;
      }
    }

    // 表格样式优化
    .el-table {
      height: 100%;

      // 表头样式
      th {
        background-color: #fafafa !important;
        color: #606266;
        font-weight: 500;
        height: 44px;
        padding: 8px 0;
        border-bottom: 1px solid #EBEEF5;
      }

      // 表格内容
      td {
        padding: 8px 0;
        height: 44px;
      }

      // 类型标签样式
      .el-tag {
        height: 24px;
        line-height: 22px;
        padding: 0 8px;
        border-radius: 2px;

        &.el-tag--success {
          background-color: #f6ffed;
          border-color: #b7eb8f;
          color: #52c41a;
        }

        &.el-tag--primary {
          background-color: #e6f7ff;
          border-color: #91d5ff;
          color: #1890ff;
        }

        &.el-tag--warning {
          background-color: #fffbe6;
          border-color: #ffe58f;
          color: #faad14;
        }

        &.el-tag--info {
          background-color: #f4f4f5;
          border-color: #e9e9eb;
          color: #909399;
        }
      }

      // 单元格内容样式
      .cell-content {
        display: flex;
        align-items: center;
        gap: 8px;

        .cell-icon {
          font-size: 14px;
          color: #909399;
        }

        span {
          color: #606266;
        }
      }

      // 表格行样式
      .el-table__row {
        &:hover {
          td {
            background-color: #f5f7fa;
          }
        }

        &.current-row {
          td {
            background-color: #e6f7ff;
          }
        }
      }

      // 表格体容器
      .el-table__body-wrapper {
        height: calc(100% - 44px); // 减去表头高度
        overflow-y: auto;
      }
    }
  }
}

.empty-tab {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;

  .empty-text {
    font-size: 14px;
    color: #606266;
    margin: 0;
  }

  .empty-subtext {
    font-size: 12px;
    color: #909399;
    margin: 8px 0 0;
  }
}

.header-actions {
  .action-wrapper {
    display: flex;
    gap: 8px;
    align-items: center;
  }

  .business-button {
    height: 32px;
    padding: 0 16px;
    border-radius: 4px;
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.3px;
    transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    position: relative;
    border: none;

    i {
      font-size: 14px;
      transition: transform 0.3s ease;
    }

    &:hover {
      transform: translateY(-1px);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);

      i {
        transform: scale(1.1);
      }
    }

    &:active {
      transform: translateY(1px);
      box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
    }

    // 主要按钮样式（刷新按钮）- 调整为更浅的蓝色
    &.el-button--primary {
      background: linear-gradient(135deg, #3b6998 0%, #2c5282 100%);
      border: none;
      color: white;

      &:hover {
        background: linear-gradient(135deg, #4575a8 0%, #365c8d 100%);
      }

      &:active {
        background: linear-gradient(135deg, #2c5282 0%, #234172 100%);
      }
    }

    // 危险按钮样式（删除按钮）
    &.is-danger {
      background: linear-gradient(135deg, #942121 0%, #7d1c1c 100%);

      &:hover {
        background: linear-gradient(135deg, #a52424 0%, #8f1f1f 100%);
      }

      &:active {
        background: linear-gradient(135deg, #7d1c1c 0%, #6b1818 100%);
      }

      &.is-disabled {
        background: #f5f5f5;
        color: #bfbfbf;
        cursor: not-allowed;
        border: 1px solid #e8e8e8;

        &:hover {
          transform: none;
          box-shadow: none;
        }

        i {
          transform: none;
        }
      }
    }
  }
}

.table-action-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  height: 28px;
  padding: 0 8px;
  color: #f5222d;
  transition: all 0.3s;
  border-radius: 4px;

  &:hover {
    color: #ff4d4f;
    background-color: #fff1f0;
  }

  &:active {
    color: #cf1322;
    background-color: #ffccc7;
  }

  i {
    font-size: 14px;
  }

  span {
    font-size: 13px;
  }
}

::v-deep {
  .el-button {
    box-shadow: 0 2px 0 rgba(0, 0, 0, 0.015);

    &:active {
      transform: translateY(1px);
    }
  }

  .el-tooltip__popper {
    padding: 6px 10px;
    font-size: 12px;
    border-radius: 4px;
    box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.08),
                0 6px 16px 0 rgba(0, 0, 0, 0.06),
                0 9px 28px 8px rgba(0, 0, 0, 0.04);
  }
}

.text-detail {
  max-height: 300px;
  overflow-y: auto;
}

.text-content {
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
  font-family: 'Courier New', monospace;
  font-size: 12px;
  line-height: 1.5;
}

.view-button {
  color: #3b6998 !important;

  &:hover {
    color: #4c84bd !important;
    background-color: #ecf5ff !important;
  }

  &:active {
    color: #2c5282 !important;
    background-color: #dbedff !important;
  }
}

.mapping-footer {
  margin-top: 15px;
  display: flex;
  justify-content: flex-end;
}

.mapping-count {
  font-weight: 500;
  font-size: 16px;
  color: #409EFF;
}

// 为弹窗添加全局样式
:deep(.mapping-detail-dialog) {
  min-width: 760px;
  max-width: 85vw;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);

  .el-message-box__header {
    background: linear-gradient(135deg, #3b6998 0%, #2c5282 100%);
    padding: 16px 24px;
    border-bottom: none;
  }

  .el-message-box__title {
    color: #fff;
    font-size: 18px;
    font-weight: 600;
    display: flex;
    align-items: center;

    &::before {
      content: "";
      display: inline-block;
      width: 3px;
      height: 16px;
      background-color: #fff;
      margin-right: 10px;
      border-radius: 1.5px;
    }
  }

  .el-message-box__headerbtn .el-message-box__close {
    color: rgba(255, 255, 255, 0.85);

    &:hover {
      color: #fff;
    }
  }

  .el-message-box__content {
    padding: 0;
    color: #606266;
  }

  .mapping-detail-container {
    max-height: 70vh;
    overflow-y: auto;
    background-color: #f8f9fa;

    &::-webkit-scrollbar {
      width: 6px;
    }

    &::-webkit-scrollbar-thumb {
      background-color: rgba(0, 0, 0, 0.1);
      border-radius: 3px;

      &:hover {
        background-color: rgba(0, 0, 0, 0.2);
      }
    }
  }

  .mapping-header {
    display: flex;
    align-items: center;
    margin: 16px 16px 24px;
    padding: 14px 20px;
    background-color: #f8f8fc;
    border-radius: 4px;
    border-left: 4px solid #2d8cf0;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.05);

    .dialog-icon {
      font-size: 24px;
      color: #2d8cf0;
      margin-right: 16px;
    }

    .mapping-subtitle {
      color: #515a6e;
      font-size: 14px;
      line-height: 1.6;
    }
  }

  /* 映射部分样式 */
  .mapping-section {
    height: 100%;
    box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.06);
    border: 1px solid #e8eaec;
    border-radius: 4px;
    margin: 0 16px 24px;
    transition: all 0.3s ease;

    &:hover {
      box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.08);
    }
  }

  .section-title {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    background-color: #f8f8fc;
    border-bottom: 1px solid #e8eaec;
    font-weight: 600;
    color: #17233d;
    border-radius: 4px 4px 0 0;

    i {
      font-size: 16px;
      margin-right: 8px;
      color: #2d8cf0;
    }

    .item-tag {
      margin-left: 8px;
    }
  }

  .section-content {
    padding: 16px;
    background-color: white;
    border-radius: 0 0 4px 4px;
  }

  .item-card {
    background-color: #f8f9fa;
    border-radius: 4px;
    padding: 12px 16px;
    border: 1px solid #e8eaec;

    .item-name {
      font-size: 16px;
      font-weight: 500;
      color: #17233d;
      margin-bottom: 8px;
    }

    .item-desc {
      display: flex;
      align-items: flex-start;
      font-size: 13px;
      color: #808695;
      line-height: 1.5;

      i {
        margin-right: 6px;
        font-size: 14px;
        margin-top: 2px;
      }

      span {
        flex: 1;
      }
    }
  }

  /* 映射概览 */
  .mapping-summary {
    margin: 0 16px 24px;
    border: 1px solid #e8eaec;
    border-radius: 4px;
    background-color: white;
    box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.06);

    .summary-title {
      display: flex;
      align-items: center;
      padding: 12px 16px;
      background-color: #f8f8fc;
      border-bottom: 1px solid #e8eaec;
      font-weight: 600;
      color: #17233d;

      i {
        font-size: 16px;
        margin-right: 8px;
        color: #2d8cf0;
      }
    }

    .summary-content {
      padding: 16px;
    }
  }

  .mapping-preview {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background-color: #f8f9fa;
    border-radius: 4px;

    .mapping-preview-left,
    .mapping-preview-right {
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    .preview-icon {
      width: 48px;
      height: 48px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-bottom: 8px;

      i {
        font-size: 24px;
        color: white;
      }

      &.demand-icon {
        background: linear-gradient(135deg, #3b6998 0%, #2c5282 100%);
      }

      &.indicator-icon {
        background: linear-gradient(135deg, #19be6b 0%, #0e9f56 100%);
      }
    }

    .preview-text {
      font-size: 14px;
      color: #515a6e;
    }

    .mapping-preview-arrow {
      display: flex;
      flex-direction: column;
      align-items: center;
      margin: 0 24px;
      position: relative;

      i {
        font-size: 24px;
        color: #808695;
        background-color: #fff;
        width: 36px;
        height: 36px;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 50%;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
      }

      &::before,
      &::after {
        content: "";
        position: absolute;
        height: 1px;
        background-color: #dcdee2;
        width: 24px;
      }

      &::before {
        left: -24px;
      }

      &::after {
        right: -24px;
      }

      .preview-count {
        position: absolute;
        top: -20px;
        background-color: #f0f0f0;
        color: #515a6e;
        font-size: 12px;
        padding: 0 8px;
        height: 20px;
        line-height: 20px;
        border-radius: 10px;
        font-weight: 500;
      }
    }
  }

  /* 映射列表 */
  .mapping-list-container {
    margin: 0 16px 24px;
    border: 1px solid #e8eaec;
    border-radius: 4px;
    background-color: white;
    box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.06);

    .mapping-list-title {
      display: flex;
      align-items: center;
      padding: 12px 16px;
      background-color: #f8f8fc;
      border-bottom: 1px solid #e8eaec;
      font-weight: 600;
      color: #17233d;

      i {
        font-size: 16px;
        margin-right: 8px;
        color: #2d8cf0;
      }

      .count-tag {
        margin-left: 8px;
      }
    }
  }

  .empty-mappings {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 40px 0;
    color: #c5c8ce;

    i {
      font-size: 48px;
      margin-bottom: 16px;
    }

    .empty-text {
      font-size: 14px;
    }
  }

  .mappings-table {
    width: 100%;

    .table-header {
      display: flex;
      background-color: #f8f8fc;
      border-bottom: 1px solid #e8eaec;

      .column-header {
        padding: 12px 16px;
        font-weight: 600;
        color: #17233d;
        font-size: 14px;
      }
    }

    .table-body {
      .table-row {
        display: flex;
        border-bottom: 1px solid #e8eaec;
        transition: all 0.3s;

        &:last-child {
          border-bottom: none;
        }

        &:hover {
          background-color: #f8f9fa;
        }

        &.deleting {
          opacity: 0;
          transform: translateX(30px);
        }
      }

      .table-cell {
        padding: 12px 16px;
        font-size: 14px;
        color: #515a6e;
      }
    }

    .demand-column {
      flex: 1;
    }

    .indicator-column {
      flex: 1;
    }

    .action-column {
      width: 80px;
      text-align: center;
    }
  }

  .mapping-item-cell {
    display: flex;
    align-items: center;

    .cell-icon {
      margin-right: 8px;
      font-size: 14px;

      &.demand-icon {
        color: #2d8cf0;
      }

      &.indicator-icon {
        color: #19be6b;
      }
    }
  }

  .delete-btn {
    background-color: #fff1f0;
    border: 1px solid #ffccc7;
    color: #f56c6c;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s;
    margin: 0 auto;

    &:hover {
      background-color: #fef0f0;
      color: #f56c6c;
      transform: scale(1.1);
      box-shadow: 0 2px 8px rgba(245, 108, 108, 0.2);

      i {
        animation: shake 0.5s ease;
      }
    }

    &:active {
      transform: scale(0.95);
    }
  }
}

.mapping-btn {
  background-color: #2d8cf0;
  border-color: #2d8cf0;
  color: white;

  &:hover {
    background-color: #57a3f3;
    border-color: #57a3f3;
    box-shadow: 0 4px 12px rgba(45, 140, 240, 0.2);
  }

  &:active {
    background-color: #2b85e4;
    border-color: #2b85e4;
  }
}

.variable-name {
  font-family: 'Courier New', monospace;
  font-weight: 600;
  color: #409EFF;
  background-color: #ecf5ff;
  padding: 2px 6px;
  border-radius: 3px;
}

.formula-cell {
  display: flex;
  align-items: center;

  .cell-icon {
    margin-right: 8px;
    color: #409EFF;
  }

  .formula-text {
    font-family: 'Courier New', monospace;
    color: #606266;
    cursor: pointer;
    &:hover {
      color: #409EFF;
      text-decoration: underline;
    }
  }
}

.formula-popover {
  .formula-title {
    font-weight: 600;
    margin-bottom: 8px;
    color: #303133;
    font-size: 14px;
  }

  .formula-content {
    font-family: 'Courier New', monospace;
    background-color: #f5f7fa;
    padding: 8px 12px;
    border-radius: 4px;
    color: #606266;
    word-break: break-all;
  }
}

/* 函数映射特定样式 */
.demand-variables-container {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;

  .demand-tag {
    margin-right: 0;
    display: inline-flex;
    align-items: center;
    padding: 3px 8px;

    .demand-name {
      font-weight: 500;
    }

    .demand-separator {
      margin: 0 4px;
      color: #909399;
    }

    .variable-name {
      font-family: 'Courier New', monospace;
      font-weight: 600;
    }
  }
}

.demands-preview {
  display: flex;
  align-items: center;
  gap: 8px;
}

.count-tag {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;

  i {
    margin-right: 4px;
  }

  span {
    font-weight: 600;
  }
}

.demands-preview-hint {
  color: #909399;
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.demands-popover {
  &-title {
    font-weight: 600;
    font-size: 14px;
    margin-bottom: 12px;
    color: #303133;
    border-bottom: 1px solid #EBEEF5;
    padding-bottom: 8px;
  }

  &-content {
    max-height: 300px;
    overflow-y: auto;
  }
}

.demand-item {
  padding: 8px 0;

  &.with-divider {
    border-bottom: 1px dashed #EBEEF5;
  }

  &-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;

    .demand-name {
      font-weight: 500;
      color: #303133;
    }
  }

  .demand-variable {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: 4px;

    i {
      color: #909399;
    }

    .variable-name {
      font-family: 'Courier New', monospace;
      font-weight: 600;
      color: #409EFF;
      background-color: #ecf5ff;
      padding: 2px 6px;
      border-radius: 3px;
    }
  }
}

.demands-preview {
  display: flex;
  align-items: center;
  gap: 8px;
}

.count-tag {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;

  i {
    font-size: 14px;
  }

  span {
    font-weight: 600;
  }
}

.demands-preview-hint {
  color: #909399;
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.demands-popover {
  &-title {
    font-weight: 600;
    font-size: 14px;
    margin-bottom: 12px;
    color: #303133;
    border-bottom: 1px solid #EBEEF5;
    padding-bottom: 8px;
  }

  &-content {
    max-height: 300px;
    overflow-y: auto;
  }
}

.demand-item {
  padding: 8px 0;

  &.with-divider {
    border-bottom: 1px dashed #EBEEF5;
  }

  &-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;

    .demand-name {
      font-weight: 500;
      color: #303133;
    }
  }

  .demand-variable {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: 4px;

    i {
      color: #909399;
    }

    .variable-name {
      font-family: 'Courier New', monospace;
      font-weight: 600;
      color: #409EFF;
      background-color: #ecf5ff;
      padding: 2px 6px;
      border-radius: 3px;
    }
  }
}

.demand-variables-list {
  margin-left: 4px;
}

.demand-variable {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;

  &.variable-divider {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px dotted #EBEEF5;
  }

  &:last-child {
    margin-bottom: 0;
  }

  i {
    color: #909399;
  }

  .variable-name {
    font-family: 'Courier New', monospace;
    font-weight: 600;
    color: #409EFF;
    background-color: #ecf5ff;
    padding: 2px 6px;
    border-radius: 3px;
  }
}
</style>


